'''This package enables the use of annotate service via python'''
import requests
import json
import pandas as pd
import os.path as osp
import logging

class Annotate(object):
    """docstring for Annotate"""

    def __init__(self, usrName, psw, root='http://annotate:8080'):
        super(Annotate, self).__init__()
        self.usrName = usrName
        self.psw = psw
        self.root = root
        # get token
        data = {
            'user_name': self.usrName,
            'password': self.psw
        }
        req = requests.post(root + '/api/get_token', data=json.dumps(data))
        self.token = json.loads(req.text)['token']
        if self.token == '':
            print('Error')

    def addImage(self, imgrec):
        assert self.token != None and self.token != ''
        payload = imgrec
        headers = {'token': self.token}
        r = requests.post(
            self.root + '/api/add_img',
            headers=headers,
            data=json.dumps(payload)
        )
        if r.status_code != 200:
            print('Error, ', imgrec, r.status_code, r.text)
            return None
        return json.loads(r.text)

    def addPatient(self, patient):
        headers = {'token': self.token}
        r = requests.post(
            self.root + '/api/add_patient',
            headers=headers,
            data=json.dumps(patient)
        )
        if r.status_code != 200:
            print('Error, ', r.status_code, r.text)
            return None
        return json.loads(r.text)

    def addSession(self, session):
        headers = {'token': self.token}
        r = requests.post(
            self.root + '/api/add_session',
            headers=headers,
            data=json.dumps(session)
        )
        if r.status_code != 200:
            print('Error, ', r.status_code, r.text)
        return json.loads(r.text)

    def addImgToSession(self, imgid, sessionid):
        headers = {'token': self.token}
        r = requests.post(
            self.root + '/api/add_img_to_session',
            headers=headers,
            data=json.dumps(dict(Session=sessionid, Image=imgid))
        )
        if r.status_code != 200:
            print('Error, ', r.status_code, r.text)
        return json.loads(r.text)

    def getImageList(self):
        # /api/get_list
        headers = {'token': self.token}
        r = requests.get(
            self.root + '/api/get_list',
            headers=headers,
            data=json.dumps(dict(offset=0, limit=20))
        )
        if r.status_code != 200:
            print('Error, ', r.status_code, r.text)
        print(r.text)
        return json.loads(r.text)


def addKaggleTrain():
    anno = Annotate('t', 't')
    file = pd.read_csv('/data/grade/trainLabels.csv')
    for i in range(file.shape[0]):
        rec = file.iloc[i]
        if rec['level'] >= 0:
            print('adding ', rec['image'])
            anno.addImage(dict(
                Path='grade/train/' + rec['image'] + '.jpeg',
                Grade=int(rec['level']),
                VisitPermision=20,
            ))


def addKaggleTest():
    anno = Annotate('t', 't')
    file = pd.read_csv('/data/grade/retinopathy_solution.csv')
    for i in range(file.shape[0]):
        rec = file.iloc[i]
        if rec['level'] > 0:
            print('adding ', rec['image'])
            anno.addImage(dict(
                Path='grade/test/' + rec['image'] + '.jpeg',
                Grade=int(rec['level'])
            ))


def addQingpuData():
    anno = Annotate('t', 't')
    lines = open('result.txt').read().splitlines()
    for l in lines:
        fields = l.split(',')
        print('adding', l)
        anno.addImage(dict(
            Path='wanda_data/data.rename/' + fields[0],
            Grade=int(fields[1])
        ))


def extractName(name):
    name = name.split('.')[0]
    name = name.split('_')
    name = '_'.join([name[0], name[1]])
    return name


def addQingPuRaw():
    anno = Annotate('t', 't')
    pdFile = pd.read_excel('/data/wanda_data/XuHui_JingShan.xls')
    imgKeys = ('照片1', '照片2', '照片3', '照片4', '照片5', '照片6', '照片7')
    # print(pdFile.keys())

    annoSessions = [x.split(',')[0].split('.')[0][:-2] for x in open('result.txt').read().splitlines()]

    for i in range(pdFile.shape[0]):
        rec = pdFile.iloc[i]
        patient = dict(
            Name=rec['姓名'],
            Id_card=str(rec['身份证号']),
            Gender=int(rec['性别'] == '男'),
            Age=int(rec['年龄']),
            District=rec['区县'],
            Community_health_service_center=rec['社区卫生服务中心'],
            Address=rec['地址'],
            Mobie=str(rec['手机号码']),
            Tel=str(rec['固定电话']),
            EyeSightLefe=str(rec['裸眼右眼视力']),
            EyeSightRight=str(rec['裸眼左眼视力']),
        )
        patient = anno.addPatient(patient)
        if patient is None:
            continue

        session = dict(
            Priority=10,
            Level=0,
            Finished=0,
        )
        # simFileName = extractName(rec['照片1'])
        # if simFileName in annoSessions or True:
        sessionL = anno.addSession(session)
        sessionR = anno.addSession(session)
        # print("Create AnnoSession for ", simFileName)
        for imageField in imgKeys:
            imgName = rec[imageField]
            if type(imgName) != str or len(imgName) < 5:
                continue
            imgName = imgName[:-3] + 'JPG'
            print("adding", imgName)
            imgrec = anno.addImage(dict(
                Path='wanda_data/data/' + imgName,
                Grade=0,  # TODO add grade here
                Patient=patient['Id'],
                # Examine_time=rec['检查日期'],
                Source="万达数据"
            ))
            if imgrec is None:
                continue
            # if simFileName in annoSessions or True:
            if imgName[-5] == 'R':
                sessionID = sessionR['Id']
            else:
                sessionID = sessionL['Id']
            anno.addImgToSession(imgrec['Id'], sessionID)


def addKaggleSessions():
    anno = Annotate('t', 't')
    file = pd.read_csv('/data/grade/retinopathy_solution.csv')
    uperLimit = 10
    # print(file.head(uperLimit))
    num_dict = {}
    for i in range(uperLimit,file.shape[0]):
        rec = file.iloc[i]
        name = rec['image']
        num = name.split('_')[0]
        level = rec['level']
        # print(num, name, level)
        if not num in num_dict:
            num_dict[num] = []
        num_dict[num].append(name)

    # print(num_dict)
    for k, v in num_dict.items():
        print("adding session", k)
        session = anno.addSession(session=dict(
            Priority=20,  # larger the priority is lower
            Level=0,
            Finished=0,
        ))
        for img in v:
            print("Adding", img)
            imgrec = anno.addImage(dict(
                Path='grade/test/' + img + '.jpeg',
                Grade=0,  # TODO add grade here
                Patient=0,
                Source="Kaggle",
                VisitPermision=20,
            ))
            anno.addImgToSession(imgrec['Id'], session['Id'])



def getLevelFile():
    imgKeys = ('照片1', '照片2', '照片3', '照片4', '照片5', '照片6', '照片7')
    def getKaggle(csvFile, dataSource):
        fields = [line.split(',') for line in open(csvFile, 'r').read().splitlines()[1:] ]
        return [(osp.join(dataSource, field[0])+'.jpeg', int(field[1])) for field in fields]

    def GetGrade(PDR, NPDRgrade):
        if PDR == '增殖期':
            return 4;
        elif PDR == '非增殖期':
            if NPDRgrade == '中度':
                return 2
            elif NPDRgrade == '重度':
                return 3
            elif NPDRgrade == '轻度':
                return 1
            else:
                logging.error('No NPDR Describe ' + str(NPDRgrade))
                return 1
        else:
            return 0

    result = []
    result += getKaggle('/data/grade/retinopathy_solution.csv', 'grade/test/')
    result += getKaggle('/data/grade/trainLabels.csv', 'grade/train/')

    def getExcel(file):
        result = []
        pdFile = pd.read_excel(file)
        for i in range(pdFile.shape[0]):
            rec = pdFile.iloc[i]
            rGrade = GetGrade(rec['疾病分期_右'], rec['非增殖期程度_右'])
            lGrade = GetGrade(rec['疾病分期_左'], rec['非增殖期程度_左'])
            for imageField in imgKeys:
                if type(rec[imageField]) != str:
                    continue
                if len(rec[imageField]) < 5:
                    continue
                imgName = rec[imageField]
                if imgName.endswith('.dcm'):
                    imgName = imgName.replace('.dcm', '.JPG')
                imgName = 'wanda_data/data/' + imgName
                if 'L' in imgName:
                    result.append((imgName, lGrade))
                elif 'R' in imgName:
                    result.append((imgName, rGrade))
                else:
                    logging.error(f'No L or R found in file:{imgName}')
        return result

    result += getExcel('/data/wanda_data/XuHui_JingShan.xls')
    result += getExcel('/data/wanda_data/QingPu.xlsx')
    with open('/workspace/GradeResult.csv', 'w') as f:
        for elem in result:
            f.write(f'{elem[0]},{elem[1]}\n')

if __name__ == '__main__':
    getLevelFile()
